﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq.Expressions;

namespace TraceView.UI.Entities
{
    public abstract class BaseEntity : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        protected void NotifyPropertyChanged<TProperty>(Expression<Func<TProperty>> property)
        {
            if (PropertyChanged == null)
                return;

            var lambda = (LambdaExpression)property;
            var unaryExpression = lambda.Body as UnaryExpression;
            MemberExpression memberExpression = unaryExpression != null
                ? (MemberExpression)unaryExpression.Operand : (MemberExpression)lambda.Body;
            PropertyChanged(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
        }

        protected void SetProperty<TProperty>(Expression<Func<TProperty>> property, ref TProperty field, TProperty value)
        {
            field = value;
            NotifyPropertyChanged(property);
        }
    }

    public abstract class BaseEntityCollection<T> : ObservableCollection<T>
        where T : BaseEntity
    {
        protected override void MoveItem(int oldIndex, int newIndex)
        {
            throw new InvalidOperationException("Cannot move an existing item in an entity collection");
        }

        protected sealed override void SetItem(int index, T item)
        {
            throw new InvalidOperationException("Cannot set an existing item in an entity collection");
        }
    }
}